package com.ibm.cloud.banking.parameter.pricing.service;

import com.ibm.cloud.banking.parameter.pricing.entity.*;
import com.ibm.cloud.banking.parameter.pricing.facade.IBaseRateLyrDefineService;
import com.ibm.cloud.banking.parameter.pricing.repo.PrpBaseRateLyrDefnMapper;
import com.ibm.cloud.banking.parameter.pricing.repo.PrpChrgDefnMapper;
import com.ibm.cloud.banking.parameter.pricing.repo.PrpFeeDfrtnDmsnlValMapper;
import com.ibm.cloud.banking.parameter.pricing.repo.PrpFeeDfrtnRuleMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.List;

@Service
public class BaseRateLyrDefineServiceImpl implements IBaseRateLyrDefineService {
    static final Logger logger = LoggerFactory.getLogger(PricingChargingInnerServiceImpl.class);
    @Autowired
    private PrpBaseRateLyrDefnMapper prpBaseRateLyrDefnMapper;

    @Autowired
    private PrpChrgDefnMapper prpChrgDefnMapper; // 收费定义dao

    @Autowired
    private PrpFeeDfrtnRuleMapper prpFeeDfrtnRuleMapper; // 费用差异化规则dao

    @Autowired
    private PrpFeeDfrtnDmsnlValMapper prpFeeDfrtnDmsnlValMapper; // 费用差异化规则维度取值dao

    /**
     * 根据条件计算得到收费金额(访问基础费率分层定义信息计算)
     *
     * @param baseRateLyrDefineParamVo 基础费率分层定义表入参Vo
     * @return
     */
    public ResultVo<BigDecimal> getFeeAmountByCondition(BaseRateLyrDefineParamVo baseRateLyrDefineParamVo) {
        ResultVo<BigDecimal> resultVo = new ResultVo<BigDecimal>();
        resultVo.setResultCode("00000");
        resultVo.setResultMsg("成功!");
        resultVo.setData(null);
        /**
         * 参数验证
         */
        if (StringUtils.isEmpty(baseRateLyrDefineParamVo.getFeeCode())
                || StringUtils.isEmpty(baseRateLyrDefineParamVo.getCurrencyCode())
                || StringUtils.isEmpty(baseRateLyrDefineParamVo.getPricingOrgNo())) {
            resultVo.setResultCode("90001");
            resultVo.setResultMsg("入参费种代码，交易币种代码，定价机构为空!");
            logger.info("入参[费种代码，交易币种代码，定价机构]为空!");
            return resultVo;
        }
        /**
         * 根据In.费种代码，In.交易币种代码，(In.定价机构，暂不用)查询基础费率分层定义信息
         */
        PrpBaseRateLyrDefn prpBaseRateLyrDefn = new PrpBaseRateLyrDefn();
        prpBaseRateLyrDefn.setFeeCode(baseRateLyrDefineParamVo.getFeeCode()); // 费用代码=In.费种代码
        prpBaseRateLyrDefn.setBillgCcyCode(baseRateLyrDefineParamVo.getCurrencyCode()); // 计费币种代码=In.交易币种代码
        // prpBaseRateLyrDefn.setPrcgOrgNum(baseRateLyrDefineParamVo.getPricingOrgNo());
        // // 定价机构编号=In.定价机构
        List<PrpBaseRateLyrDefn> prpBaseRateLyrDefnList = prpBaseRateLyrDefnMapper
                .findPrpBaseRateLyrDefnListByCondition(prpBaseRateLyrDefn);
        if (StringUtils.isEmpty(prpBaseRateLyrDefnList)) {
            resultVo.setResultCode("90001");
            resultVo.setResultMsg("没有查询到数据!");
            logger.info("[根据条件计算得到收费金额(访问基础费率分层定义信息计算),没有查询到数据]");
            return resultVo;
        }
        PrpBaseRateLyrDefn resultBo = prpBaseRateLyrDefnList.get(0);
        if (StringUtils.isEmpty(resultBo.getBillgTpCode()) && StringUtils.isEmpty(resultBo.getChrgStdAmt())
                && StringUtils.isEmpty(resultBo.getChrgStdPct())
                && StringUtils.isEmpty(resultBo.getChrgUprLmt())
                && StringUtils.isEmpty(resultBo.getChrgLwrLmt())) {
            resultVo.setResultCode("90001");
            resultVo.setResultMsg("基础费率分层定义数据异常，未找到配置项!");
            logger.info("[计费类型代码、收费标准金额、收费标准比例、收费上限、收费下限]为空，请检查基础费率分层定义配置项!");
            return resultVo;
        }
        BigDecimal feeAmount = new BigDecimal("0");
        if (resultBo.getBillgTpCode().equals("1")) { // 如果计费类型代码=1-按固定金额
            // out.收费金额=基础费率分层定义表.收费标准金额
            feeAmount = new BigDecimal(resultBo.getChrgStdAmt());
        } else if (resultBo.getBillgTpCode().equals("2")) { // 如果计费类型代码=2-按固定比例
            // out.收费金额=In.交易金额*基础费率分层定义表.收费标准比例
            feeAmount = baseRateLyrDefineParamVo.getTransAmount().multiply(new BigDecimal(resultBo.getChrgStdPct()));
        }
        // 如果 out.收费金额>基础费率分层定义表.收费上限,out.收费金额 = 基础费率分层定义表.收费上限
        if (feeAmount.compareTo(new BigDecimal(resultBo.getChrgUprLmt())) == 1) {
            feeAmount = new BigDecimal(resultBo.getChrgUprLmt());
        }
        // 如果out.收费金额<基础费率分层定义表.收费下限,out.收费金额 = 基础费率分层定义表.收费下限
        if (feeAmount.compareTo(new BigDecimal(resultBo.getChrgLwrLmt())) == -1) {
            feeAmount = new BigDecimal(resultBo.getChrgLwrLmt());
        }
        feeAmount = feeAmount.setScale(2, BigDecimal.ROUND_HALF_UP);
        resultVo.setData(feeAmount);
        return resultVo;
    }

    /**
     * 根据条件计算得到收费金额(访问基础费率分层定义信息计算),目前仅定价内部使用
     *
     * @param pricingChargeParamVo     交易入参信息
     * @return
     */
    @Override
    public ResultVo<FeeCalculateResultVo> getFeeAmountInnerByCondition(
            BaseRateLyrDefineParamVo baseRateLyrDefineParamVo, PricingChargeParamVo pricingChargeParamVo) {
        FeeCalculateResultVo feeCalculateResultVo = new FeeCalculateResultVo();
        ResultVo<FeeCalculateResultVo> resultVo = new ResultVo<FeeCalculateResultVo>();
        resultVo.setResultCode("00000");
        resultVo.setResultMsg("成功!");
        resultVo.setData(null);
        /**
         * 参数验证
         */
        if (StringUtils.isEmpty(baseRateLyrDefineParamVo.getFeeCode())
                || StringUtils.isEmpty(baseRateLyrDefineParamVo.getCurrencyCode())
                || StringUtils.isEmpty(baseRateLyrDefineParamVo.getPricingOrgNo())) {
            resultVo.setResultCode("90001");
            resultVo.setResultMsg("入参费种代码，交易币种代码，定价机构为空!");
            logger.info("入参[费种代码，交易币种代码，定价机构]为空!");
            return resultVo;
        }
        String feeCode = baseRateLyrDefineParamVo.getFeeCode(); // 费用代码
        String currencyCode = baseRateLyrDefineParamVo.getCurrencyCode(); // 计费币种
        /**
         * 根据In.费种代码，In.交易币种代码，(In.定价机构，暂不用)查询基础费率分层定义信息
         */
        PrpBaseRateLyrDefn prpBaseRateLyrDefn = new PrpBaseRateLyrDefn();
        prpBaseRateLyrDefn.setFeeCode(feeCode); // 费用代码=In.费种代码
        prpBaseRateLyrDefn.setBillgCcyCode(currencyCode); // 计费币种代码=In.交易币种代码
        // prpBaseRateLyrDefn.setPrcgOrgNum(baseRateLyrDefineParamVo.getPricingOrgNo());
        // 定价机构编号=In.定价机构
        List<PrpBaseRateLyrDefn> prpBaseRateLyrDefnList = prpBaseRateLyrDefnMapper
                .findPrpBaseRateLyrDefnListByCondition(prpBaseRateLyrDefn);
        if (StringUtils.isEmpty(prpBaseRateLyrDefnList)) {
            resultVo.setResultCode("90001");
            resultVo.setResultMsg("没有查询到基础费率分层定义信息数据!");
            logger.info("[根据条件计算得到收费金额(访问基础费率分层定义信息计算),没有查询到数据]");
            return resultVo;
        }
        PrpBaseRateLyrDefn resultBo = prpBaseRateLyrDefnList.get(0);
        if (StringUtils.isEmpty(resultBo.getBillgTpCode()) && StringUtils.isEmpty(resultBo.getChrgStdAmt())
                && StringUtils.isEmpty(resultBo.getChrgStdPct())
                && StringUtils.isEmpty(resultBo.getChrgUprLmt())
                && StringUtils.isEmpty(resultBo.getChrgLwrLmt())) {
            resultVo.setResultCode("90001");
            resultVo.setResultMsg("基础费率分层定义数据异常，未找到配置项!");
            logger.info("[计费类型代码、收费标准金额、收费标准比例、收费上限、收费下限]为空，请检查基础费率分层定义配置项!");
            return resultVo;
        }
        BigDecimal tmpFeeAmount = new BigDecimal("0"); // 收费金额，临时变量
        if (resultBo.getBillgTpCode().equals("1")) { // 如果计费类型代码=1-按固定金额
            // wk.收费金额=基础费率分层定义表.收费标准金额
            tmpFeeAmount = new BigDecimal(resultBo.getChrgStdAmt());
        } else if (resultBo.getBillgTpCode().equals("2")) { // 如果计费类型代码=2-按固定比例
            // wk.收费金额=In.交易金额*基础费率分层定义表.收费标准比例
            tmpFeeAmount = baseRateLyrDefineParamVo.getTransAmount().multiply(new BigDecimal(resultBo.getChrgStdPct()));
        }
        BigDecimal jzsfAmount = tmpFeeAmount; // Out.基准收费金额 = wk.收费金额

        /**
         * 通过In.客户账户调用合约接口获取客户编号
         */
//        String accountNo = pricingChargeParamVo.getBusinessSceneInfoVo().getAccountNo();
//        Map<String, Object> depositandDrawInfoMap = accountManagementService.findDepositandDrawInfo(accountNo, null,
//                null, null);
//        if (StringUtils.isEmpty(depositandDrawInfoMap)
//                || StringUtils.isEmpty(depositandDrawInfoMap.get("memberInfo"))) {
//            resultVo.setResultCode("90001");
//            resultVo.setResultMsg("根据客户账户" + accountNo + "调用合约获取客户编号失败，没有查询到客户编号!");
//            logger.info("根据客户账户" + accountNo + "调用合约获取客户编号失败，没有查询到客户编号!");
//            return resultVo;
//        }
//        MemberInfo memberInfo = (MemberInfo) depositandDrawInfoMap.get("memberInfo");
//        if (StringUtils.isEmpty(memberInfo.getCustNo())) {
//            resultVo.setResultCode("90001");
//            resultVo.setResultMsg("获取客户对象未得到客户编号!");
//            logger.info("获取客户对象未得到客户编号!");
//            return resultVo;
//        }
//        String custNo = memberInfo.getCustNo(); // 客户编号
        /**
         * 使in.费用代码访问收费定义表，取筛选策略，赋值临时变量Wk.筛选策略
         */
        PrpChrgDefn prpChrgDefnQueryParam = new PrpChrgDefn();
        prpChrgDefnQueryParam.setFeeCode(feeCode);
        List<PrpChrgDefn> prpChrgDefnResultBoList = prpChrgDefnMapper.findPrpChrgDefnByCondition(prpChrgDefnQueryParam);
        if (StringUtils.isEmpty(prpChrgDefnResultBoList)) {
            resultVo.setResultCode("90001");
            resultVo.setResultMsg("根据费用代码" + feeCode + "查询收费定义失败，未查询到数据!");
            logger.info("根据费用代码" + feeCode + "查询收费定义失败，未查询到数据!");
            return resultVo;
        }
        PrpChrgDefn prpChrgDefnResultBo = prpChrgDefnResultBoList.get(0);
        // Out.筛选策略 = Wk.筛选策略
        String tmpSxcl = prpChrgDefnResultBo.getRsrvFld41Bits();
        String sxcl = tmpSxcl;

        BigDecimal tmpGxhje = new BigDecimal("0"); // Wk.个性化金额
        /**
         * 使用In.客户号访问收费个性化合约，获取 差异化形式代码，优惠调整比例和优惠调整金额，分别赋值临时变量wk1.
         * 差异化形式代码，wk1.优惠调整比例和wk1.优惠调整金额
         */
        boolean isGxhgz = false; // 是否有个性化规则
//        PrpPslznAgrm prpPslznAgrmQueryParam = new PrpPslznAgrm();
//        prpPslznAgrmQueryParam.setCstNum(custNo);
//        List<PrpPslznAgrm> prpPslznAgrmResultBoList = prpPslznAgrmDao
//                .findPrpPslznAgrmByCondition(prpPslznAgrmQueryParam);
//		if (StringUtils.isEmpty(prpPslznAgrmResultBoList)) {
//			resultVo.setResultCode("90001");
//			resultVo.setResultMsg("根据客户号" + custNo + "收费个性化合约失败，未查询到数据!");
//			logger.info("根据客户号" + custNo + "收费个性化合约失败，未查询到数据!");
//			return resultVo;
//		}
        // 如果找到个性化合约协议
//        if (prpPslznAgrmResultBoList != null && !prpPslznAgrmResultBoList.isEmpty()) {
//            isGxhgz = true;
//            PrpPslznAgrm prpPslznAgrmResultBo = prpPslznAgrmResultBoList.get(0);
//            String pslznAgrmNum = prpPslznAgrmResultBo.getPslznAgrmNum();// 个性化合约编号
//            if (StringUtils.isEmpty(pslznAgrmNum)) {
//                resultVo.setResultCode("90001");
//                resultVo.setResultMsg("个性化合约编号为空!pslznAgrmNum=" + pslznAgrmNum);
//                logger.info("个性化合约编号为空!pslznAgrmNum=" + pslznAgrmNum);
//                return resultVo;
//            }
//            // 根据个性化合约编号和费种代码查询个性化合约计费信息，从而得到差异化形式代码，优惠调整比例和优惠调整金额
//            PrpPslznAgrmBillg prpPslznAgrmBillg = new PrpPslznAgrmBillg();
//            prpPslznAgrmBillg.setPslznAgrmNum(pslznAgrmNum);
//            prpPslznAgrmBillg.setFeeCode(feeCode);
//            List<PrpPslznAgrmBillg> prpPslznAgrmBillgResultBoList = prpPslznAgrmBillgMapper
//                    .findPrpPslznAgrmBillgByCondition(prpPslznAgrmBillg);
//            if (StringUtils.isEmpty(prpPslznAgrmBillgResultBoList)) {
//                resultVo.setResultCode("90001");
//                resultVo.setResultMsg("根据个性化合约编号" + pslznAgrmNum + "和费种代码" + feeCode + "查询个性化合约计费信息失败，未查询到数据!");
//                logger.info("根据个性化合约编号" + pslznAgrmNum + "和费种代码" + feeCode + "查询个性化合约计费信息失败，未查询到数据!");
//                return resultVo;
//            }
//            PrpPslznAgrmBillg prpPslznAgrmBillgResultBo = prpPslznAgrmBillgResultBoList.get(0);
//            String tmpCyhxsdm = prpPslznAgrmBillgResultBo.getDfrtnFormCode(); // 差异化形式代码
//            BigDecimal tmpYhtzbl = prpPslznAgrmBillgResultBo.getPrefAdjPct(); // 优惠调整比例
//            BigDecimal tmpYhtzje = prpPslznAgrmBillgResultBo.getPrefAdjAmt(); // 优惠调整金额
//
//            if (StringUtils.isEmpty(tmpCyhxsdm)) {
//                resultVo.setResultCode("90001");
//                resultVo.setResultMsg("个性化合约编号" + pslznAgrmNum + "和费种代码" + feeCode + "对应的个性化合约计费信息的差异化形式代码为空");
//                logger.info("个性化合约编号" + pslznAgrmNum + "和费种代码" + feeCode + "对应的个性化合约计费信息的差异化形式代码为空");
//                return resultVo;
//            }
//
//            // 如果wk1 .差异化形式代码 = 1-全免,Wk.个性化金额=0
//            if (tmpCyhxsdm.equals("1")) {
//                tmpGxhje = new BigDecimal("0");
//            }
//            // 如果差异化形式代码 =2-比例调整,Wk.个性化金额=wk.收费金额*（1- wk1.优惠调整比例）
//            if (tmpCyhxsdm.equals("2")) {
//                tmpGxhje = tmpFeeAmount.multiply(new BigDecimal("1").subtract(tmpYhtzbl));
//            }
//            // 如果差异化形式代码 =3-金额调整,Wk.个性化金额=wk.收费金额- wk1.优惠调整金额
//            if (tmpCyhxsdm.equals("3")) {
//                tmpGxhje = tmpFeeAmount.subtract(tmpYhtzje);
//            }
//        }
        if (tmpGxhje.compareTo(new BigDecimal("0.00")) != 0) {
            tmpGxhje = tmpGxhje.setScale(2, BigDecimal.ROUND_HALF_UP);
        }

        /**
         * 使用In.费中代码和差异化模式赋值1-直接优惠，两个条件访问费用差异化规则表，获取差异化形式代码，差异化调整比例和差异化调整金额，
         * 分别赋值临时变量wk2. 差异化形式代码，wk2. 差异化调整比例和wk2. 差异化调整金额
         */
        boolean isCyhgz = false; // 是否有差异化规则
        BigDecimal tmpYhAmount = new BigDecimal("0"); // Wk.优惠金额
        PrpFeeDfrtnRule prpFeeDfrtnRuleQueryParam = new PrpFeeDfrtnRule();
        prpFeeDfrtnRuleQueryParam.setFeeCode(feeCode);
        prpFeeDfrtnRuleQueryParam.setDfrtnPtrnCode("1"); // 1-直接优惠
        List<PrpFeeDfrtnRule> prpFeeDfrtnRuleResultBoList = prpFeeDfrtnRuleMapper
                .findPrpFeeDfrtnRuleByCondition(prpFeeDfrtnRuleQueryParam);
//		if (StringUtils.isEmpty(prpFeeDfrtnRuleResultBoList)) {
//			resultVo.setResultCode("90001");
//			resultVo.setResultMsg("根据1-直接优惠费种代码" + feeCode + "查询费用差异化规则信息失败，未查询到数据!");
//			logger.info("根据1-直接优惠费种代码" + feeCode + "查询费用差异化规则信息失败，未查询到数据!");
//			return resultVo;
//		}
        // 找到差异化规则
        if (prpFeeDfrtnRuleResultBoList != null && !prpFeeDfrtnRuleResultBoList.isEmpty()) {
            isCyhgz = true;
            PrpFeeDfrtnRule prpFeeDfrtnRuleResultBo = prpFeeDfrtnRuleResultBoList.get(0);
            String tmpCyhxsdm2 = prpFeeDfrtnRuleResultBo.getDfrtnFormCode(); // 差异化形式代码
            BigDecimal tmpCyhtzbl = prpFeeDfrtnRuleResultBo.getDfrtnAdjPct(); // 差异化调整比例
            BigDecimal tmpCyhtzje = prpFeeDfrtnRuleResultBo.getDfrtnAdjAmt(); // 差异化调整金额
            if (StringUtils.isEmpty(tmpCyhxsdm2)) {
                resultVo.setResultCode("90001");
                resultVo.setResultMsg("1-直接优惠费种代码" + feeCode + "对应的费用差异化规则信息的差异化形式代码为空");
                logger.info("1-直接优惠费种代码" + feeCode + "对应的费用差异化规则信息的差异化形式代码为空");
                return resultVo;
            }

            // 如果wk2.差异化形式代码 = 1-全免,Wk.优惠金额=0
            if (tmpCyhxsdm2.equals("1")) {
                tmpYhAmount = new BigDecimal("0");
            }
            // 如果差异化形式代码 =2-比例调整,Wk.优惠金额=wk.收费金额*（1- wk2.差异化调整比例）
            if (tmpCyhxsdm2.equals("2")) {
                tmpYhAmount = tmpFeeAmount.multiply(new BigDecimal("1").subtract(tmpCyhtzbl));
            }
            // 如果差异化形式代码 =3-金额调整,Wk.优惠金额=wk.收费金额- wk2.差异化调整金额
            if (tmpCyhxsdm2.equals("3")) {
                tmpYhAmount = tmpFeeAmount.subtract(tmpCyhtzje);
            }
        }

        /**
         * 如果有个性化金额(即配置了个性化协议)，则比较
         */
        if (!isGxhgz) {
            // 如果找不到差异化规则
            if (!isCyhgz) {
                //wk.收费金额 = Out.基准收费金额
                tmpFeeAmount = jzsfAmount;
            }else {
                tmpFeeAmount = tmpYhAmount;
            }
        } else {
            // 如果wk.筛选策略等与1-比价
            if (!StringUtils.isEmpty(tmpSxcl) && tmpSxcl.equals("1")) {
                // 如果 Wk.个性化金额 >= Wk.优惠金额,wk.收费金额 = Wk.优惠金额
                if (tmpGxhje.compareTo(tmpYhAmount) != -1) {
                    tmpFeeAmount = tmpYhAmount;
                } else {
                    // wk.收费金额 = Wk.个性化金额
                    tmpFeeAmount = tmpGxhje;
                }
            }
            // 如果wk.筛选策略等与0-不比价,wk.收费金额 = Wk.个性化金额
            if (!StringUtils.isEmpty(tmpSxcl) && tmpSxcl.equals("0")) {
                tmpFeeAmount = tmpGxhje;
            }
        }

        BigDecimal yhsfAmount = tmpYhAmount; // Out.优惠收费金额=Wk.优惠金额
        BigDecimal xysfAmount = tmpGxhje; // Out.协议收费金额=Wk.个性化金额
        BigDecimal feeAmount = tmpFeeAmount; // out.收费金额=wk.收费金额

        // 如果 out.收费金额>基础费率分层定义表.收费上限,out.收费金额 = 基础费率分层定义表.收费上限
        if (feeAmount.compareTo(new BigDecimal(resultBo.getChrgUprLmt())) == 1) {
            feeAmount = new BigDecimal(resultBo.getChrgUprLmt());
        }
        // 如果out.收费金额<基础费率分层定义表.收费下限,out.收费金额 = 基础费率分层定义表.收费下限
        if (feeAmount.compareTo(new BigDecimal(resultBo.getChrgLwrLmt())) == -1) {
            feeAmount = new BigDecimal(resultBo.getChrgLwrLmt());
        }
        feeAmount = feeAmount.setScale(2, BigDecimal.ROUND_HALF_UP);
        jzsfAmount = jzsfAmount.setScale(2, BigDecimal.ROUND_HALF_UP);
        yhsfAmount = yhsfAmount.setScale(2, BigDecimal.ROUND_HALF_UP);
        xysfAmount = xysfAmount.setScale(2, BigDecimal.ROUND_HALF_UP);
        /**
         * 设置返回Vo的参数
         */
        feeCalculateResultVo.setFeeCode(feeCode);
        feeCalculateResultVo.setBillCycCode(currencyCode);
        feeCalculateResultVo.setFeeAmount(feeAmount);
        feeCalculateResultVo.setJzsfAmount(jzsfAmount);
        feeCalculateResultVo.setSxcl(sxcl);
        feeCalculateResultVo.setXysfAmount(xysfAmount);
        feeCalculateResultVo.setYhsfAmount(yhsfAmount);
        // 返回结果
        resultVo.setData(feeCalculateResultVo);
        return resultVo;
    }
}
